package com.taokatao.cardmee;

import android.content.Context;
import android.support.multidex.MultiDexApplication;

import com.alibaba.sdk.android.feedback.impl.FeedbackAPI;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.google.gson.Gson;
import com.lody.turbodex.TurboDex;
import com.taokatao.cardmee.db.DaoMaster;
import com.taokatao.cardmee.db.DaoSession;
import com.taokatao.cardmee.db.UserDao;
import com.taokatao.cardmee.db.model.User;
import com.taokatao.cardmee.db.upgrade.UpgradeableOpenHelper;
import com.taokatao.cardmee.util.DiskLruCacheUtils;
import com.umeng.analytics.MobclickAgent;
import com.umeng.socialize.PlatformConfig;

import org.greenrobot.greendao.query.QueryBuilder;

import cn.jpush.android.api.JPushInterface;
import jp.wasabeef.glide.transformations.CropCircleTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;


public class App extends MultiDexApplication {

    private static App instance;
    private Gson gson;
    private DiskLruCacheUtils diskLruCacheUtils;
    private CropCircleTransformation cctf;
    private RoundedCornersTransformation rctf;
    private int d1;
    private int dbUserVersion, dbCommonVersion;

    private AMapLocationClient locationClient;

    private UpgradeableOpenHelper dbCommonHelper;
    private DaoSession dbCommonDaoSession;
    private UpgradeableOpenHelper dbUserHelper;
    private DaoSession dbUserDaoSession;

    private User currUser;

    /**
     * true 含日志  # false 不含日志
     */
    public static final boolean DEBUG_LOG = false; // 一般打线上版改为false， 其它时间全为true
    /**
     * true 测试服务器 # false 正式服务
     */
    public static final boolean DEBUG_SERVICE = false;

    @Override
    protected void attachBaseContext(Context base) {
        TurboDex.enableTurboDex();
        super.attachBaseContext(base);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;

        MobclickAgent.setDebugMode(DEBUG_LOG);
        QueryBuilder.LOG_SQL = DEBUG_LOG;
        QueryBuilder.LOG_VALUES = DEBUG_LOG;
        Utils.DEBUG = DEBUG_LOG;
        Utils.TAG = "cardmee";

        JPushInterface.setDebugMode(DEBUG_LOG);
        JPushInterface.init(this);

        FeedbackAPI.initAnnoy(this, "23430145");

        PlatformConfig.setWeixin("wx83e5d9a490e5a129", "49a9df4aea4188abdf99ba7e8eed818a");
        PlatformConfig.setQQZone("1105481655", "0cfLYIlKS7JEesKR");
        PlatformConfig.setSinaWeibo("1240072160", "8d656fefc5f797ae87f369434b53641d");

//            PlatformConfig.setWeixin("wxb6a618bc95ddde71", "0b0a6919d9010ab706dcdbd294d51d37");
//            PlatformConfig.setQQZone("1105839620", "hoYLzNCkh0vlj7Ah");
//            PlatformConfig.setSinaWeibo("793305123", "0f820732e92728c1d1f1bdb78813fe64");


        registerCrashHandler();
    }

    public static synchronized App i() {
        return instance;
    }

    public Gson getGson() {
        if (gson == null) {
            gson = new Gson();
        }
        return gson;
    }

    public CropCircleTransformation getCropCircleTransformation() {
        if (cctf == null) {
            cctf = new CropCircleTransformation(this);
        }
        return cctf;
    }

    public RoundedCornersTransformation getRoundedCornersTransformation() {
        if (rctf == null) {
            rctf = new RoundedCornersTransformation(this, d1() * 5, 0);
        }
        return rctf;
    }

    public DiskLruCacheUtils getHttpCacheUtils() {
        if (diskLruCacheUtils == null) {
            diskLruCacheUtils = DiskLruCacheUtils.open(this, "http");
        }
        return diskLruCacheUtils;
    }

    /**
     * 获得公用数据库的操作（session）对象
     */
    public synchronized DaoSession getCommonDBSession() {
        if (dbCommonDaoSession != null) {
            dbCommonDaoSession.clear();
            return dbCommonDaoSession;
        }

        if (dbCommonHelper != null && dbCommonVersion < DaoMaster.SCHEMA_VERSION) {
            dbCommonHelper.close();
            dbCommonHelper = null;
        }

        if (dbCommonHelper == null) {
            dbCommonHelper = new UpgradeableOpenHelper(this, "db_common");
            dbCommonVersion = DaoMaster.SCHEMA_VERSION;
        }
        DaoMaster daoMaster = new DaoMaster(dbCommonHelper.getWritableDatabase());
        return dbCommonDaoSession = daoMaster.newSession();
    }

    public synchronized DaoSession getUserDBSession() {
        getCurrUser();
        return getUserDBSession(currUser.getUuid());
    }

    /**
     * 拿取User数据库连接(session)对象
     * 在第一次登录 或者切换用户的时候使用
     */
    private synchronized DaoSession getUserDBSession(long uuid) {
        if (dbUserDaoSession != null) {
            dbUserDaoSession.clear();
        }
        if (dbUserHelper != null && (currUser == null || currUser.getUuid() != uuid)) {
            dbUserHelper.close();
            dbUserHelper = null;
        }
        if (dbUserHelper != null && dbUserVersion < DaoMaster.SCHEMA_VERSION) {
            dbUserHelper.close();
            dbUserHelper = null;
        }

        if (dbUserHelper == null) {
            dbUserHelper = new UpgradeableOpenHelper(this, "db_user_" + uuid);
            Utils.logd("greenDAO dbUserHelper = new UpgradeableOpenHelper()");
            DaoMaster daoMaster = new DaoMaster(dbUserHelper.getWritableDatabase());
            dbUserDaoSession = daoMaster.newSession();
            dbUserVersion = DaoMaster.SCHEMA_VERSION;

            Utils.postMainThreadBusEvent(BusEvent.ACTION_USER_SWITCH);
        }
        return dbUserDaoSession;
    }

    public int d1() {
        if (d1 > 0) return d1;
        return d1 = (int) (1 * getResources().getDisplayMetrics().density + 0.5f);
    }

    public User getCurrUser() {
        if (currUser == null) {
            Long lastUuid = Utils.spReadLong(C.sp.CURRENT_LOGIN_USER_ID);
            if (lastUuid > 0) {
                UserDao userDao = getUserDBSession(lastUuid).getUserDao();
                currUser = userDao.queryBuilder().where(UserDao.Properties.Uuid.eq(lastUuid)).unique();
            }
        }
        return currUser;
    }

    /**
     * 设置全局User对象， 一般登录或者切换用户的时候调用
     */
    public synchronized void setCurrUser(User source) {
        if (source == null) {
            if (dbUserDaoSession != null) {
                dbUserDaoSession.clear();
                dbUserDaoSession = null;
            }
            if (dbUserHelper != null) {
                dbUserHelper.close();
                dbUserHelper = null;
            }
            currUser = null;
            Utils.spWrite(C.sp.CURRENT_LOGIN_USER_ID, 0);
            Utils.postMainThreadBusEvent(BusEvent.USER_PROFILE_INFO_CHANGED);
        } else {
            UserDao userDao = getUserDBSession(source.getUuid()).getUserDao();
            userDao.insertOrReplaceInTx(currUser = source);

            Utils.spWrite(C.sp.CURRENT_LOGIN_USER_ID, currUser.getUuid());
            Utils.postMainThreadBusEvent(BusEvent.USER_PROFILE_INFO_CHANGED);
        }
    }

    public AMapLocationClient getAMapLocationClient() {
        if (locationClient == null) {
            locationClient = new AMapLocationClient(getApplicationContext());
            locationClient.setLocationOption(new AMapLocationClientOption().setOnceLocation(true));
        }
        return locationClient;
    }

    /**
     * 发生崩溃立即闪退处理，避免不必要的错误连续发生
     */
    private void registerCrashHandler() {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {
                ex.printStackTrace();
                Utils.recordCrashInfo(getApplicationContext(), ex);
                MobclickAgent.reportError(getApplicationContext(), ex);

                if (!DEBUG_LOG) {
                    try {
                        Thread.sleep(C.settings.ANIMATION_TIME);
                    } catch (InterruptedException ignored) {
                    } finally {
                        ActivityCollector.finishAll();
                    }
                }
            }
        });
    }
}
